# -*- coding: utf-8 -*-
# @Time    : 2020/12/8 15:47
# @Author  : huangwei
# @File    : inotify.py
# @Software: PyCharm
import sys, os, filetype, pyinotify
from img_function import *
from video_function import *
from psnr import *

"""
    监控目录，包含图片和视频的目录
    1. 判断是否有图片发送到文件夹 /home/data/picture/origin 中，再对发送来的图片进行加水印操作
    2. 判断是否有视频发送到文件夹 /home/data/video/origin 中，再对发送来的视频进行加水印操作
    3. 判断是否有图片发送到文件夹 /home/data/solution/picture/origin 中，再对发送来的图片进行解水印操作
    4. 判断是否有视频发送到文件夹 /home/data/solution/video/origin 中，再对发送来的视频进行解水印操作
"""
WATCH_PATH = '/home/data'
ORIGIN_IMG_PATH = '/home/data/picture/origin'
ORIGIN_VIDEO_PATH = '/home/data/video/origin'
TARGET_IMG_PATH = '/home/data/picture/target'
TARGET_VIDEO_PATH = '/home/data/video/target'

# 传入文件目录，来判断是否存在水印，如果存在则解出水印，不存在则解出一张空白图
SOLUTION_ORIGIN_IMG_PATH = '/home/data/solution/picture/origin'
SOLUTION_ORIGIN_VIDEO_PATH = '/home/data/solution/video/origin'
SOLUTION_TARGET_IMG_PATH = '/home/data/solution/picture/target'
SOLUTION_TARGET_VIDEO_PATH = '/home/data/solution/video/target'

# 水印存储目录，水印图片固定不变
WATERMARK_PATH = '/home/data/watermark/watermark.png'
# 空白水印路径
BLACK_PATH = '/home/data/watermark/blank.png'

# 可选的音视频种类
image_type = ['image/jpeg', 'image/png', 'image/gif', 'image/x-canon-cr2', 'image/bmp', 'image/vnd.adobe.photoshop',
              'image/x-icon']
video_type = ['video/mp4', 'video/x-msvideo', 'video/x-flv', 'video/quicktime']

# 判断监控目录是否存在
if not WATCH_PATH:
    print("The WATCH_PATH IS NO VALUE!")
    sys.exit()
else:
    if os.path.exists(WATCH_PATH):
        print('FOUND WATCH PATH: path=%s.' % WATCH_PATH)
    else:
        print('WATCH PATH IS NOT EXISTS, path= %s.' % WATCH_PATH)
        sys.exit()


class OnFileHandler(pyinotify.ProcessEvent):
    """
        定义事件回调函数和相应文件变化后的操作
    """

    def process_IN_CLOSE_WRITE( self, event ):
        """ 文件完全写入 """
        print("文件完成写入: %s " % os.path.join(event.path, event.name))

        # 判断文件写入路径为 图片 文件夹 还是 视频 文件夹
        if event.path == ORIGIN_IMG_PATH:

            kind = filetype.guess(event.pathname)

            # 判断传入的文件是否符合 图片 类型
            if kind is not None and kind.mime in image_type:
                input_filepath = event.pathname  # 传入文件路径

                # 拼接输出文件路径
                (filename, extension) = os.path.splitext(event.name)  # 分割文件名和后缀

                # 判断输入图片是否已经加过了水印，如果已经加过，则提取出水印，否则加水印
                find_watermark_path = "{0}/{1}_dark.png".format(TARGET_IMG_PATH, filename)
                exist_watermark = img_extract_watermark(input_filepath, find_watermark_path)

                if not exist_watermark:
                    output_filepath = "{0}/{1}_darkmark{2}".format(TARGET_IMG_PATH, filename, extension)
                    # 插入数字水印
                    img_insert_watermark(input_filepath, WATERMARK_PATH, output_filepath)

                    # 查看前后的 psnr 值
                    psnr_value = psnr(input_filepath, output_filepath)
                    print("psnr value is :", psnr_value)
                    if psnr_value < 30:
                        print("使用这个方法添加暗水印效果不太好！")

            else:
                print("传入的图片不符合要求的图片类型！")

        elif event.path == ORIGIN_VIDEO_PATH:

            kind = filetype.guess(event.pathname)

            # 判断传入的文件符合 视频 类型
            if kind is not None and kind.mime in video_type:
                input_filepath = event.pathname

                # 拼接输出文件路径
                (filename, extension) = os.path.splitext(event.name)  # 分割文件名和后缀

                # 判断输入视频是否加过水印
                # 如果存在水印，水印的保存路径，否则跳过
                find_watermark_path = "{0}/{1}_dark.png".format(TARGET_VIDEO_PATH, filename)
                # 判断视频中是否存在水印，如果存在则解出水印，不存在则返回false，下一步往视频中添加水印
                exist_watermark = video_extract_watermark(input_filepath, find_watermark_path)

                if not exist_watermark:
                    # 插入可见水印
                    output_filepath = "{0}/{1}_mark{2}".format(TARGET_VIDEO_PATH, filename, extension)
                    video_add_visual_watermark(input_filepath, WATERMARK_PATH, output_filepath)

                    """插入数字水印"""
                    # 输出文件 应该是  mp4 类型
                    output_filepath = "{0}/{1}_darkmark.mp4".format(TARGET_VIDEO_PATH, filename)
                    video_insert_watermark(input_filepath, WATERMARK_PATH, output_filepath)
            else:
                print("传入的视频不符合要求的视频类型！")

        elif event.path == SOLUTION_ORIGIN_IMG_PATH:
            """用于单独从图片或视频中解出水印"""

            kind = filetype.guess(event.pathname)

            # 判断传入的文件是否符合 图片 类型
            if kind is not None and kind.mime in image_type:
                input_filepath = event.pathname  # 传入文件路径

                # 拼接输出文件路径
                (filename, extension) = os.path.splitext(event.name)  # 分割文件名和后缀

                # 判断输入图片是否已经加过了水印，如果已经加过，则提取出水印，否则加水印
                find_watermark_path = "{0}/{1}_dark.png".format(SOLUTION_TARGET_IMG_PATH, filename)
                exist_watermark = img_extract_watermark(input_filepath, find_watermark_path)

                if not exist_watermark:
                    # 将空白水印复制过来
                    os.system("cp {0} {1}".format(BLACK_PATH, find_watermark_path))



            else:
                print("传入的图片不符合要求的图片类型！")

        elif event.path == SOLUTION_ORIGIN_VIDEO_PATH:

            kind = filetype.guess(event.pathname)

            # 判断传入的文件符合 视频 类型
            if kind is not None and kind.mime in video_type:
                input_filepath = event.pathname

                # 拼接输出文件路径
                (filename, extension) = os.path.splitext(event.name)  # 分割文件名和后缀

                # 判断输入视频是否加过水印
                find_watermark_path = "{0}/{1}_dark.png".format(SOLUTION_TARGET_VIDEO_PATH, filename)
                # 判断视频中是否存在水印，如果存在则解出水印，不存在则返回false
                exist_watermark = video_extract_watermark(input_filepath, find_watermark_path)
                if not exist_watermark:
                    # 将空白水印复制过来
                    os.system("cp {0} {1}".format(BLACK_PATH, find_watermark_path))

            else:
                print("传入的视频不符合要求的视频类型！")

    def process_IN_DELETE( self, event ):
        """ 文件删除 """
        print("文件删除: %s " % os.path.join(event.path, event.name))

    def process_IN_CREATE( self, event ):
        """ 文件创建 """
        print("文件创建: %s " % os.path.join(event.path, event.name))


def auto_compile( path='.' ):
    watch = pyinotify.WatchManager()

    # 监控内容
    mask = pyinotify.IN_CREATE | pyinotify.IN_DELETE | pyinotify.IN_CLOSE_WRITE

    notifier = pyinotify.Notifier(watch, OnFileHandler())

    watch.add_watch(path, mask, rec=True, auto_add=True)
    print("start monitoring %s" % path)

    while True:
        try:
            notifier.process_events()
            if notifier.check_events():
                notifier.read_events()
        except KeyboardInterrupt:
            notifier.stop()
            break


if __name__ == '__main__':
    auto_compile(WATCH_PATH)
    print("monitor close.")
